/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.yaps.petstore.dao.impl;

import com.yaps.petstore.dao.CustomerDAO;
import com.yaps.petstore.dao.CategoryDAO;
import com.yaps.petstore.entity.customer.Address;
import com.yaps.petstore.entity.customer.Customer;
import com.yaps.petstore.exception.ValidationException;
import com.yaps.petstore.util.Constants;
import java.util.List;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author pfa
 */
@Repository("CustomerDAO")
public class CustomerDAOImpl implements CustomerDAO  {
	@PersistenceContext
	private EntityManager em;

    private final String cname = this.getClass().getName();
    private Logger logger = Logger.getLogger(Constants.LOGGER_STATELESS);
    
    @Override
      public Customer authenticate(final String login, final String password) {
        final String mname = "authenticate";
        logger.entering(cname, mname, new Object[]{login, password});

        // On s'assure de la validité des paramètres
        if (login == null || "".equals(login))
            throw new ValidationException("Invalid login");

        Query query;
        Customer customer;

        // On recherche l'objet à partir de son login
        query = em.createQuery("SELECT c FROM Customer c WHERE c.login=:login");
        query.setParameter("login", login);
        customer = (Customer) query.getSingleResult();

        // Check if it's the right password
        if (customer != null)
            customer.matchPassword(password);

        logger.exiting(cname, mname, customer);
        return customer;
    }

    
    @Transactional
    @Override
    public Customer createCustomer(final Customer customer, final Address homeAddress) {
        final String mname = "createCustomer";
        logger.entering(cname, mname, customer);

        // On s'assure de la validité des paramètres
        if (customer == null)
            throw new ValidationException("Customer object is null");

        customer.setHomeAddress(homeAddress);
    em.persist(customer);

        logger.exiting(cname, mname, customer);
        return customer;
    }

    @Override
    public Customer findCustomer(final Long customerId) {
        final String mname = "findCustomer";
        logger.entering(cname, mname, customerId);

        // On s'assure de la validité des paramètres
        if (customerId == null)
            throw new ValidationException("Invalid id");

        Customer customer;

        // On recherche l'objet à partir de son identifiant
        customer = em.find(Customer.class, customerId);

        logger.exiting(cname, mname, customer);
        return customer;
    }

    
    @Transactional
    @Override
    public void deleteCustomer(final Customer customer) {
        final String mname = "deleteCustomer";
        logger.entering(cname, mname, customer);

        // On s'assure de la validité des paramètres
        if (customer == null)
            throw new ValidationException("Customer object is null");

        // On supprime l'objet de la base de données
        em.remove(em.merge(customer));

        logger.exiting(cname, mname);
    }

    
    @Transactional
    @Override
    public Customer updateCustomer(final Customer customer, final Address homeAddress) {
        final String mname = "updateCustomer";
        logger.entering(cname, mname, customer);

        // On s'assure de la validité des paramètres
        if (customer == null)
            throw new ValidationException("Customer object is null");

        customer.setHomeAddress(homeAddress);

        // On modifie l'objet de la base de données
        em.merge(customer);

        logger.exiting(cname, mname, customer);
        return customer;
    }

    @Override
    public List<Customer> findCustomers() {
        final String mname = "findCustomers";
        logger.entering(cname, mname);

        Query query;
        List<Customer> customers;

        // On modifie l'objet de la base de données
        query = em.createQuery("SELECT c FROM Customer c");
        customers = query.getResultList();

        logger.exiting(cname, mname, customers.size());
        return customers;
    }

}
